package cfca.seal.web.action.maintain;

import cfca.seal.bean.Seal;
import cfca.seal.exception.CodeException;
import cfca.seal.system.Env;
import cfca.seal.util.TimeUtil;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping({"/backupSeal"})
public class BackupSealAction
{
  private static final Logger log = LoggerFactory.getLogger("web_sys");
  private static byte[] buffer = new byte[4096];

  @RequestMapping({"/v_list"})
  public String viewList(HttpServletRequest request, Seal seal)
    throws CodeException
  {
    return "sys/backup/list.html";
  }

  @RequestMapping({"/o_backup_seal"})
  public String backup(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response)
    throws CodeException
  {
    log.info("电子印章配置备份开始");
    String zipFileName = new StringBuilder().append("seal_config_").append(TimeUtil.getCurrentTime().getTime()).append(".zip").toString();
    ZipOutputStream zos = null;
    FileInputStream fis = null;
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    try {
      log.info("开始压缩印章配置文件和相关印章资源");
      zos = new ZipOutputStream(byteArrayOutputStream);

      log.info("正在压缩印章配置文件db文件");
      String dbfill = getClass().getClassLoader().getResource("sqlite.db").getPath();
      ZipEntry entry = new ZipEntry("sqlite.db");
      zos.putNextEntry(entry);
      int count = 0;
      fis = new FileInputStream(dbfill);
      while ((count = fis.read(buffer, 0, buffer.length)) != -1) {
        zos.write(buffer, 0, count);
      }

      File sealTRusterrRsourceDir = new File(new StringBuilder().append(Env.configDir).append(File.separator).append("cert").toString());
      log.info(new StringBuilder().append("正在压缩印章相关资源文件,共个数：").append(sealTRusterrRsourceDir.isDirectory() ? sealTRusterrRsourceDir.listFiles().length : 0).toString());
      fis = zipDir(zos, fis, sealTRusterrRsourceDir, "cert");
      File sealCrlResourceDir = new File(new StringBuilder().append(Env.configDir).append(File.separator).append("crl").toString());

      log.info(new StringBuilder().append("正在压缩印章相关资源文件,共个数：").append(sealCrlResourceDir.isDirectory() ? sealCrlResourceDir.listFiles().length : 0).toString());
      fis = zipDir(zos, fis, sealCrlResourceDir, "crl");
    } catch (Exception e) {
      log.error("压缩文件失败", e);
      throw new CodeException("C0001", "压缩文件失败", e);
    } finally {
      try {
        if (zos != null) {
          zos.close();
          zos = null;
        }
        if (fis != null) {
          fis.close();
          fis = null;
        }
      } catch (IOException e) {
      }
    }
    log.info("电子印章配置备份成功");
    log.info("电子印章配置备份成功");
    log.info("签章成功，准备下载文件");
    log.info("开始下载");
    OutputStream outputStream = null;
    try {
      response.reset();
      response.setContentType("text/html; charset=utf-8");
      response.addHeader("content-type", "application/x-msdownload;");
      response.addHeader("Content-Disposition", new StringBuilder().append("attachment;filename=").append(URLEncoder.encode(zipFileName, "UTF-8")).toString());
      response.addHeader("Content-Length", new StringBuilder().append("").append(byteArrayOutputStream.toByteArray().length).toString());
      outputStream = new BufferedOutputStream(response.getOutputStream());
      outputStream.write(byteArrayOutputStream.toByteArray());
      outputStream.flush();
    }
    catch (IOException e) {
      e.printStackTrace();
      log.error("下载PDF失败", e);
      throw new CodeException("C0001", "下载备份操作记录失败", e);
    } finally {
      try {
        if (outputStream != null)
          outputStream.close();
      }
      catch (IOException e)
      {
      }
    }
    log.info(new StringBuilder().append(zipFileName).append(":下载成功").toString());
    return "";
  }

  private FileInputStream zipDir(ZipOutputStream zos, FileInputStream fis, File zipFile, String path)
    throws IOException, FileNotFoundException
  {
    for (File resFile : zipFile.listFiles()) {
      if (resFile.isDirectory()) {
        zipDir(zos, fis, resFile, new StringBuilder().append(path).append(File.separator).append(resFile.getName()).toString());
      } else {
        ZipEntry entry2 = new ZipEntry(new StringBuilder().append(path).append(File.separator).append(resFile.getName()).toString());
        zos.putNextEntry(entry2);
        fis = new FileInputStream(resFile);
        int count;
        while ((count = fis.read(buffer, 0, buffer.length)) != -1) {
          zos.write(buffer, 0, count);
        }
      }
    }
    return fis;
  }
}